package com.sskj.gateway.protocol;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sskj.common.constant.RabbitMQConstant;
import com.sskj.common.dto.CommunicationProtocolDto;
import com.sskj.protocol.IProtocol;
import com.sskj.protocol.annotation.CommunicationProtocol;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class ProtocolScanner {

    @Autowired
    private ProtocolRegistry protocolRegistry;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    @EventListener(ContextRefreshedEvent.class)
    public void scanProtocols() {
        log.info("执行通信协议扫描注册");

        Map<String, IProtocol> beans = applicationContext.getBeansOfType(IProtocol.class);
        log.info("beans={}", beans);

        List<CommunicationProtocolDto> communicationProtocolDtoList = new ArrayList<>();
        for (Map.Entry<String, IProtocol> entry : beans.entrySet()) {
            IProtocol protocol = entry.getValue();

            // 获取类上的 @CommunicationProtocol 注解
            Class<?> clazz = protocol.getClass();
            CommunicationProtocol annotation = AnnotationUtils.findAnnotation(clazz, CommunicationProtocol.class);

            if (annotation != null) {
                String code = annotation.code();
                protocolRegistry.register(code, protocol);

                CommunicationProtocolDto protocolDto = new CommunicationProtocolDto();
                protocolDto.setName(annotation.name());
                protocolDto.setCode(code);
                protocolDto.setDescription(annotation.description());
                communicationProtocolDtoList.add(protocolDto);
            } else {
                log.warn("Protocol missing @CommunicationProtocol: {}", clazz.getSimpleName());
            }
        }

        // 发送到消息队列并进行持久化
        try {
            amqpTemplate.convertAndSend(RabbitMQConstant.DEVICE_EXCHANGE, RabbitMQConstant.DEVICE_PROTOCOL_REGISTER_ROUTEING_KEY, objectMapper.writeValueAsString(communicationProtocolDtoList));
        } catch (JsonProcessingException e) {
            log.error("[通信协议注册]-投递注册信息异常。异常信息:{}", e.getMessage());
        }
    }
}
